/*
 * Copyright 2011 Sina.
 *
 * Licensed under the Apache License and Weibo License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.open.weibo.com
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.appwx.sdk.model;


import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.CookieSyncManager;
import android.widget.Toast;

import com.appwx.sdk.app.AppLoger;
import com.appwx.sdk.app.Constants;
import com.appwx.sdk.http.Oauth2AccessTokenHeader;
import com.appwx.sdk.http.Utility;
import com.appwx.sdk.view.WeiboDialog;
import com.appwx.sdk.view.WeiboDialogListener;
import com.appwx.sdk.view.WeiboError;
import com.appwx.sdk.view.WeiboException;


public class OpenApiModel {

	public static final int TYPE_SINA_WEIBO = 1;
	public static final int TYPE_TX_WEIBO = 2;
	public static final int TYPE_TX_QQ = 3;
	public static final int TYPE_RENREN = 4;
	public static final int TYPE_KAIXIN = 5;
	public static final int TYPE_BAIDU = 6;
	
	public static final int LENGTH_LONG = Toast.LENGTH_LONG;  
	public static final int LENGTH_SHORT = Toast.LENGTH_SHORT; 
	
	public static final String TOKEN = "access_token";
	public static final String EXPIRES = "expires_in";
	public static final String OPENID = "openid";
	public static final String REFRESHTOKEN = "refresh_token";
	public static final String UID = "uid";
	public static final String DEFAULT_REDIRECT_URI = "wbconnect://success";// 暂不支持
    public static final String DEFAULT_CANCEL_URI = "wbconnect://cancel";// 暂不支持
	
    
    private static final String TAG = "OpenApiModel";
    private static final int DEFAULT_AUTH_ACTIVITY_CODE = 32973;
    
	private static String APP_KEY = "";
	private static String APP_SECRET = "";
	private static OpenApiModel openApiModel = null;
	
	private static String oauthorize_url = "";
	private static String accesstoken_url = "";
	
	
	private Token accessToken = null;
	private RequestToken requestToken = null;
	
	private int app_type = 1; // app类型 1:新浪。2：QQ ；3：人人
	
	private String redirectUrl;//重定向地址

	private WeiboDialogListener mAuthDialogListener;
	

	public OpenApiModel() {
		Utility.setRequestHeader("Accept-Encoding", "gzip");
		Utility.setTokenObject(this.accessToken);
		redirectUrl = DEFAULT_CANCEL_URI;
	}

	public synchronized static OpenApiModel getInstance(){
		if(openApiModel == null){
			openApiModel = new OpenApiModel();
		}
		return openApiModel;
	}

	public void setupConsumerConfig(String app_key,String app_secret,int app_type){
		OpenApiModel.APP_KEY = app_key;
		OpenApiModel.APP_SECRET = app_secret;
		setApp_type(app_type);
		setOAuthUrl(app_type);
	}
	
	public void setOAuthUrl(int app_type){
		switch (app_type) {
		case TYPE_SINA_WEIBO:
			setOauthorize_url(Constants.SINA_OAUTHORIZE_URL);
			setAccesstoken_url(Constants.SINA_ACCESS_TOKEN);
			break;
		case TYPE_TX_WEIBO:
			setOauthorize_url(Constants.TENCENT_WEIBO_OAUTHORIZE_URL);
			setAccesstoken_url(Constants.TENCENT_WEIBO_ACCESS_TOKEN);
			break;
		case TYPE_TX_QQ:
			setOauthorize_url(Constants.TENCENT_QQ_OAUTHORIZE_URL);
			setAccesstoken_url(Constants.TENCENT_QQ_ACCESS_TOKEN);
			break;
		case TYPE_RENREN:
			setOauthorize_url(Constants.RENREN_OAUTHORIZE_URL);
			setAccesstoken_url(Constants.RENREN_ACCESS_TOKEN_URL);
			break;
		case TYPE_KAIXIN:
			setOauthorize_url(Constants.KAIXIN_OAUTHORIZE_URL);
			setAccesstoken_url(Constants.KAIXIN_ACCESS_TOKEN_URL);
			break;
		case TYPE_BAIDU:
			setOauthorize_url(Constants.BAIDU_OAUTHORIZE_URL);
			setAccesstoken_url(Constants.BAIDU_ACCESS_TOKEN_URL);
			break;
		default:
			break;
		}
	}

	/**
	 * 请求授权
	 * @param context 上下文
	 * @param url 请求URL
	 * @param parameters 参数
	 * @param httpMethod 请求方法
	 * @param token  授权令牌
	 * @return
	 * @throws WeiboException 
	 */
	public String request(Context context, String url,AppParameters parameters, String httpMethod, Token token) throws WeiboException {
		
		return Utility.openUrl(context, url, httpMethod, parameters, token);
	}
	
	/**
     * User-Agent Flow
     * 
     * @param activity
     * 
     * @param listener
     *            授权结果监听器
     */
    public void authorize(Activity activity, final WeiboDialogListener listener) {
       
        if(this.app_type == OpenApiModel.TYPE_RENREN){
        	authorize(activity, new String[]{"create_album ","status_update","send_message"}, DEFAULT_AUTH_ACTIVITY_CODE, listener);
        }else if(this.app_type == OpenApiModel.TYPE_TX_WEIBO){
        	authorize(activity, new String[]{}, DEFAULT_AUTH_ACTIVITY_CODE, listener);
        }else if(this.app_type == OpenApiModel.TYPE_TX_QQ){
        	authorize(activity, new String[]{"get_user_info","list_album","upload_pic","do_like"}, DEFAULT_AUTH_ACTIVITY_CODE, listener);
        }else{
        	 authorize(activity, new String[] {}, listener);
        }
        
    }
	
    /**
     * 授权
     * @param activity
     * @param permissions 访问权限(例：scope)
     * @param listener 回调监听
     */
    private void authorize(Activity activity, String[] permissions,final WeiboDialogListener listener){
    	authorize(activity, new String[]{}, DEFAULT_AUTH_ACTIVITY_CODE, listener);
    }
    
    private void authorize(Activity activity, String[] permissions, int activityCode,
            final WeiboDialogListener listener) {
        Utility.setAuthorization(new Oauth2AccessTokenHeader());

        boolean singleSignOnStarted = false;
        mAuthDialogListener = listener;

        // Prefer single sign-on, where available.
        if (activityCode >= 0) {
            singleSignOnStarted = startSingleSignOn(activity, APP_KEY, permissions, activityCode);
        }
        // Otherwise fall back to traditional dialog.
        if (!singleSignOnStarted) {
            startDialogAuth(activity, permissions);
        }

    }
	
    public boolean isSessionValid() {
        if (accessToken != null) {
        	AppLoger.info(TAG,"Authorizes Success! access_token=" + accessToken.getToken() + " expires="
                    + accessToken.getExpiresIn());
            return (!TextUtils.isEmpty(accessToken.getToken()) && (accessToken.getExpiresIn() == 0 || (System
                    .currentTimeMillis()/1000 < accessToken.getExpiresIn())));
        }
        return false;
    }
	
    public void dialog(Context context, AppParameters parameters,
            final WeiboDialogListener listener) {
        parameters.add("client_id", getAPP_KEY());
        parameters.add("response_type", "token");
        parameters.add("redirect_uri", redirectUrl);
        parameters.add("display", "mobile");

        if (isSessionValid()) {
            parameters.add(TOKEN, accessToken.getToken());
        }
        String url = getOauthorize_url() + "?" + Utility.encodeUrl(parameters);
        if (context.checkCallingOrSelfPermission(Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
            Utility.showAlert(context, "Error",
                    "Application requires permission to access the Internet");
        } else {
            new WeiboDialog(this, context, url, listener).show();
        }
    }
	
    private boolean startSingleSignOn(Activity activity, String applicationId,
            String[] permissions, int activityCode) {
        return false;
    }

    private void startDialogAuth(Activity activity, String[] permissions) {
        AppParameters params = new AppParameters();
        if (permissions.length > 0) {
            params.add("scope", TextUtils.join(",", permissions));
        }
        CookieSyncManager.createInstance(activity);
        dialog(activity, params, new WeiboDialogListener() {

            public void onComplete(Bundle values) {
                CookieSyncManager.getInstance().sync();
                if (null == accessToken) {
                    accessToken = new Token();
                }
                AppLoger.info(TAG, "token =" + values.getString(TOKEN) + "&expires_in=" + values.getString(EXPIRES));
                accessToken.setToken(values.getString(TOKEN));
                accessToken.setExpiresIn(values.getString(EXPIRES));
                accessToken.setOpenId(values.getString(OpenApiModel.OPENID));
                accessToken.setRefreshToken(values.getString(OpenApiModel.REFRESHTOKEN));
                accessToken.setOpenId(values.getString(UID));
                accessToken.setKeySrc(app_type);
                if (isSessionValid()) {
                	AppLoger.info(TAG,"Authorizes Success! access_token=" + accessToken.getToken() + " expires="
                                    + accessToken.getExpiresIn());
                    mAuthDialogListener.onComplete(values);
                } else {
                	AppLoger.info(TAG, "Failed to receive access token");
                    mAuthDialogListener.onWeiboException(new WeiboException(
                            "Failed to receive access token."));
                }
            }

            public void onError(WeiboError error) {
            	AppLoger.error(TAG, "Login failed: " + error);
                mAuthDialogListener.onError(error);
            }

            public void onWeiboException(WeiboException error) {
            	AppLoger.error(TAG, "Login failed: " + error);
                mAuthDialogListener.onWeiboException(error);
            }

            public void onCancel() {
            	AppLoger.error(TAG, "Login canceled");
                mAuthDialogListener.onCancel();
            }
        });
    }
	
	public static String getAPP_KEY() {
		return OpenApiModel.APP_KEY;
	}

	public static String getAPP_SECRET() {
		return OpenApiModel.APP_SECRET;
	}

	public int getApp_type() {
		return app_type;
	}
	
	public void setApp_type(int app_type) {
		this.app_type = app_type;
	}

	public String getRedirectUrl() {
		return redirectUrl;
	}
	
	public void setRedirectUrl(String redirectUrl) {
		this.redirectUrl = redirectUrl;
	}

	public void setAccessToken(Token accessToken) {
		this.accessToken = accessToken;
		this.accessToken.setKeySrc(getApp_type());
	}

	public Token getAccessToken() {
		if(accessToken == null){
			accessToken = new Token();
		}
		return accessToken;
	}
	
	public RequestToken getRequestToken() {
		return requestToken;
	}

	public static String getOauthorize_url() {
		return oauthorize_url;
	}

	public static void setOauthorize_url(String oauthorize_url) {
		OpenApiModel.oauthorize_url = oauthorize_url;
	}

	public static String getAccesstoken_url() {
		return accesstoken_url;
	}

	public static void setAccesstoken_url(String accesstoken_url) {
		OpenApiModel.accesstoken_url = accesstoken_url;
	}
	
	
}